package com.easy.cloud.web.module.certification.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.easy.cloud.web.component.core.constants.GlobalCommonConstants;
import com.easy.cloud.web.component.core.exception.BusinessException;
import com.easy.cloud.web.component.core.util.BeanUtils;
import com.easy.cloud.web.module.certification.api.dto.DisabilityLevelDTO;
import com.easy.cloud.web.module.certification.api.vo.DisabilityLevelVO;
import com.easy.cloud.web.module.certification.biz.converter.DisabilityLevelConverter;
import com.easy.cloud.web.module.certification.biz.domain.DisabilityLevelDO;
import com.easy.cloud.web.module.certification.biz.repository.DisabilityLevelRepository;
import com.easy.cloud.web.module.certification.biz.service.IDisabilityLevelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * DisabilityLevel 业务逻辑
 *
 * @author Fast Java
 * @date 2024-04-02 20:43:33
 */
@Slf4j
@Service
public class DisabilityLevelServiceImpl implements IDisabilityLevelService {

    @Autowired
    private DisabilityLevelRepository disabilityLevelRepository;

    @Override
    @Transactional(rollbackOn = Exception.class)
    public DisabilityLevelVO save(DisabilityLevelDTO disabilityLevelDTO) {
        // 若父级ID为空，则设置默认父级ID
        if (StrUtil.isBlank(disabilityLevelDTO.getParentId())) {
            disabilityLevelDTO.setParentId(GlobalCommonConstants.DEPART_TREE_ROOT_ID);
        }

        // 转换成DO对象
        DisabilityLevelDO disabilityLevel = DisabilityLevelConverter.convertTo(disabilityLevelDTO);
        // TODO 校验逻辑

        // 同一层级下是否存在相同等级
        Optional<DisabilityLevelDO> disabilityLevelOptional = disabilityLevelRepository
                .findByParentIdAndName(disabilityLevelDTO.getParentId(), disabilityLevelDTO.getName());
        if (disabilityLevelOptional.isPresent()) {
            throw new BusinessException("当前层级下存在相同的等级名称");
        }

        // 存储
        disabilityLevelRepository.save(disabilityLevel);
        // 转换对象
        return DisabilityLevelConverter.convertTo(disabilityLevel);
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public DisabilityLevelVO update(DisabilityLevelDTO disabilityLevelDTO) {
        // 更新操作，ID不能为空
        if (Objects.isNull(disabilityLevelDTO.getId())) {
            throw new RuntimeException("当前更新对象ID为空");
        }

        // 若父级ID为空，则设置默认父级ID
        if (StrUtil.isBlank(disabilityLevelDTO.getParentId())) {
            disabilityLevelDTO.setParentId(GlobalCommonConstants.DEPART_TREE_ROOT_ID);
        }

        // 获取当前菜单信息
        DisabilityLevelDO disabilityLevel = disabilityLevelRepository.findById(disabilityLevelDTO.getId())
                .orElseThrow(() -> new BusinessException("当前伤残等级不存在"));

        // 同一层级下是否存在相同等级
        Optional<DisabilityLevelDO> disabilityLevelOptional = disabilityLevelRepository
                .findByParentIdAndName(disabilityLevelDTO.getParentId(), disabilityLevelDTO.getName());
        if (disabilityLevelOptional.isPresent()) {
            DisabilityLevelDO disabilityLevelDO = disabilityLevelOptional.get();
            // 存在同名，但不是同一个数据，则禁止更新
            if (!disabilityLevelDO.getId().equals(disabilityLevelDTO.getId())) {
                throw new BusinessException("当前伤残等级已存在");
            }
        }

        // 将修改的数据赋值给数据库数据
        BeanUtils.copyProperties(disabilityLevelDTO, disabilityLevel, true);
        // 保存
        disabilityLevelRepository.save(disabilityLevel);
        // 转换对象
        return DisabilityLevelConverter.convertTo(disabilityLevel);
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public Boolean removeById(String disabilityLevelId) {
        // TODO 业务逻辑校验

        if (disabilityLevelRepository.countByParentId(disabilityLevelId) > 0) {
            throw new BusinessException("当前数据下存在子集，请先删除子集");
        }

        // 删除
        disabilityLevelRepository.deleteById(disabilityLevelId);
        return true;
    }

    @Override
    public DisabilityLevelVO detailById(String disabilityLevelId) {
        // TODO 业务逻辑校验

        // 删除
        DisabilityLevelDO disabilityLevel = disabilityLevelRepository.findById(disabilityLevelId)
                .orElseThrow(() -> new RuntimeException("当前数据不存在"));
        // 转换对象
        return DisabilityLevelConverter.convertTo(disabilityLevel);
    }

    @Override
    public List<Tree<String>> tree(String parentId) {
        List<DisabilityLevelVO> disabilityLevels = DisabilityLevelConverter.convertTo(disabilityLevelRepository.findAll());
        return TreeUtil
                .build(disabilityLevels, GlobalCommonConstants.DEPART_TREE_ROOT_ID, (disabilityLevel, tree) -> {
                    tree.setId(disabilityLevel.getId());
                    tree.setName(disabilityLevel.getName());
                    tree.setParentId(disabilityLevel.getParentId());
                    tree.setWeight(disabilityLevel.getSort());
                    // 装载所有数据
                    tree.putAll(BeanUtil.beanToMap(disabilityLevel));
                });
    }
}